Ders 28 - Concurrency > Shopping Cart Concurrency Flaw
Concurrency(Eşzamanlılık) ünitesinin ikinci dersi olan Shopping Cart Concurrency Flaw(Alışveriş Sepeti Eşzamanlılık Açığı) dersinde alışveriş sepetindeki eşyanın eşzamanlılık bug'ı kullanılarak nasıl ucuza alınabileceğinden bahsedilecektir.

Dersin Hedefi

Bu egzersizde hedefiniz bir malı daha düşük fiyata eşzamanlılık durumunu exploit ederek - sömürerek - almaktır.

Dersin Çözümü

Dersin sunduğu alışveriş similasyonunda 4 tane ürün görüntülenmektedir. 4 üründen kaç tane alınacaksa yanlarına adedlerini girilebileceğimiz metin kutuları mevcuttur. Bu metin kutuları doldurulup Sepeti Güncelle(Update Cart) butonuna tıklanıldığında aynı sayfada kalınmakla beraber sunucuya yeni ürün adetleri bilgisi gönderilir ve böylece tablo verileri güncellenir. Bu sayfada aynı zamanda satın al(Purchase) butonu da mevcuttur. Eğer sepet güncellenmeden girilen ürün adetlerini takriben Purchase butonuna tıklanılırsa sepet yine güncellenmiş olur. Kodlar buna göre ayarlanmıştır. Aynı zamanda kodlara göre Purchase(Satın Al) butonuna basıldığı takdirde tablodaki toplam fiyatlar(Total) sunucudaki runningTotal adlı değişkende toplanır ve en sonunda calcTotal değişkenine runningTotal değişkeni atanır. Purchase(Satın Al) butonuna tıklanıldıktan sonra gelen sayfada onayla(Confirm) butonu bulunmaktadır. Confirm butonuna tıklanıldığı takdirde kod bazında tablo güncellenmesi yapılmadan var olan bilgilerle işlem sonlandırılır. Bu şekilde kodlanmış e-ticaret sitelerinde geliştirici sonuç olarak şu mantığı kurmuş olmalıdır ki bu şekilde tercihini kullanmış ve kodlamış: "Ödeme onaylama aşamasına gelene kadar zaten müşteri tablodan istediği ölçüde adet verisi girmiştir. Bu girilmiş veriler satın al(Purchase) butonuna tıklanılması sonucu calcTotal adlı değişkende toplanmıştır. E artık tablo işlemi geride kaldığına göre müşterinin yapacağı sadece ödemeyi onayla(Confirm) demek ya da işlemi iptal et(Cancel) demektir. Dolayısıyla ilk iki durumda(Update Cart ve Purchase butonlarının yer aldığı sayfada) ürün adetleri ve toplam fiyatlar(Total) hesaplanırken, yani tablo güncellenmesi yapılırken son aşamada(Confirm ve Cancel butonlarının yer aldığı sayfada) ürün adetleri ve toplam fiyatların(Total'ın) hesaplanmasına gerek yoktur." Bu mantıkla giden geliştirici son aşamada ürün adedini ve toplam fiyatlarını(Total'ı) güncellemeyi gereksiz, fazlalık gibi gördüğünden bilmeden bir açık vermiş oldu. Kötü niyetli bir müşteri eşzamanlı bir alışveriş yaparak bu açıktan faydalanabilir ve pahalı ürünü ucuz ürün fiyatına alabilir. Peki ama nasıl?

Bu açıktan bir müşteri şöyle faydalanabilir: Aynı alışveriş yapabileceği sayfadan iki tane açar. Tarayıcısındaki ilk sekmedekine A penceresi, ikinci sekmedekine ise B penceresi diyelim. Bu kötü niyetli müşterinin amacı pahalı bir ürünü ucuza almaktır. A penceresinde diyelim ki ucuz bir ürün için adet sayısına 1 girer ve Purchase butonuna tıklar. A penceresinin ekranında ucuz olan 1 adet ürünün satın alımını onaylamak için onayla(Confirm) butonu ve sembolik olarak müşterinin değişiklik yaptığı tablo yalnızca okunabilir formatta görüntülenir. Müşteri, B penceresinde ise çok pahalı bir ürünün yanına adet olarak 1 girmiş olsun ve önceki sayfada 1 adet dediği ürün dahil diğerleri 0 adet kalsın. Bu noktadan sonra yapılacak olan işlem önce B penceresinde 1 adetlik pahalı ürün için sepeti güncelle(Update Cart) demektir. Sonra A penceresinde onayla(Confirm) demektir. Böylece ucuz fiyata pahalı ürün almış oluruz.













Peki biz ne yaptık da ucuz ürün fiyatına pahalı ürün alabildik? Ucuz ürün fiyatına pahalı ürün alabilmemimizin nedeni kredi kartından kesilecek fatura miktarını tutan calcTotal adlı değişkenin kritik noktalarda güncellenmemesinden dolayıdır. Müşteri ucuz ürünle onaylama(Confirm - Cancel) aşamasına geldiğinde zaten calcTotal değişkeni hesaplanmıştır. Çünkü calcTotal değişkeni sadece Purchase(Satın Al) butonuna basılmasıyla hesaplanmaktadır. Bundan önceki aşamada yer alan Sepeti güncelle(Update Cart) butonuna basıldığında ise calcTotal hesaplaması yapılmamaktadır. Müşteri B penceresinde sepeti güncelle dediğinde B penceresindeki ürün adetlerini güncellediği gibi A penceresindeki sepetleri de güncellemiştir. Çünkü aynı istemci ve aynı oturum ile siteye bağlı bulunmaktayız ve dikkat edin: Henüz B penceresinde Purchase butonuna basmadık. Dolayısıyla henüz kredi kartından kesilecek para miktarı değişmemiştir. A penceresindeki mevcut hesaplanmış calcTotal ucuz fiyatta iken görsel planda olmasa da B penceresinde sepeti güncellediğimiz için sunucudaki değişkenler bazında ucuz ürünün adeti 0 olmuştur ve pahalı ürünün adeti 1 olmuştur. A penceresindeki onayla(Confirm) butonuna tıklanıldığında sunucudaki son güncel calcTotal ile son güncel ürün miktarına sahip ürün alınmış olur.

Özetleyecek olursak A penceresi calcTotal'ı ucuz ürün fiyatıyla doldurttu. B penceresi de sepeti pahalı ürünle doldurttu. A penceresinde Confirm butonuna basarak ucuz calcTotal değeri ve pahalı sepet ile alışverişi noktalamış oluyoruz.

Bu açığı kapatmanın yolu her üç duruma da(Update Cart, Purchase ve Confirm) calcTotal hesaplamasının dahil edilmesidir. Böylece yapılan her bir değişiklik kredi kartından kesilecek fatura değerini değiştirecektir ve eşzamanlılık bug'ı ortadan kalkacağından ucuz ürün fiyatına pahalı ürün alınması gibi bir durum ortadan kalkmış olacaktır.
Bu yazı 11.09.2015 tarihinde, saat 14:02:51'de yazılmıştır. 23.09.2015 tarihi ve 17:16:58 saatinde ise güncellenmiştir.
Yazar : Hasan Fatih ŞİMŞEK Görüntülenme Sayısı : 1677
Yorumlar
Henüz yorum girilmemiştir.
Yorum Ekle
*
* (E-posta adresiniz yayınlanmayacaktır.)
*
*

#Arşiv


#Giriş

ID :
Şifre :